package com.yx.changdao.common.utils;

import com.yx.changdao.common.annotation.Dict;
import com.yx.changdao.common.annotation.DictParam;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description: <br>
 * 解析 Dict 工具 用与返回前台数据或导出数据时使用。
 * <p><br>
 * @Auther: Zhangjiashun
 * @create 2019/11/20 11:32
 */
public class ParseDictUtils {

    /**
     * 将 T 类中所有标注Dict的属性 字典替换。
     *
     * @param obj 待解析对象
     * @param <T> 类
     * @return 解析后的值
     */
    public static <T> Map<String, Object> parseItem(T obj) {

        if (obj == null) {
            return null;
        }

        // 获取类中所有成员属性。
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        // 用于存放结果
        Map<String, Object> result = new LinkedHashMap<>();
        // 遍历所有成员属性。
        for (Field field : declaredFields) {
            // get方法名。
            String getMethodName =
                    "get" + field.getName().substring(0, 1).toUpperCase() +
                            field.getName().substring(1);
            // 将该属性名驼峰转下划线。
            String lineName = SysUtils.hump2Line(field.getName());
            Dict annotation = field.getAnnotation(Dict.class);
            Object val;
            try {
                // 调用成员的get方法 如果异常说名没有这个方法或者调用失败  直接继续下一次循环
                val = obj.getClass().getMethod(getMethodName).invoke(obj);
            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                continue;
            }
            // 判断是否标注 Dict 注解
            if (annotation != null) {
                // 获取所有 DictParam
                DictParam[] dicts = annotation.dicts();
                for (DictParam dict : dicts) {
                    // 如果注解上的key 与 get方法得到的返回值相同，说明这个值需要替换。
                    if (val != null && dict.key().equals(val.toString())) {
                        result.put(lineName, dict.value());
                    }
                }
            } else {
                // 没标注 Dict 注解的直接取原值。
                result.put(lineName, val);
            }
        }

        return result;
    }

    /**
     * 解析列表 dict 将 T 类中所有标注Dict的属性 字典替换。
     *
     * @param list 列表
     * @param <T>  类
     * @return 解析后的列表
     */
    public static <T> List<Map<String, Object>> parseList(List<T> list) {
        if (list == null || list.size() == 0) {
            return null;
        }
        List<Map<String, Object>> result = new ArrayList<>();
        for (T t : list) {
            Map<String, Object> parse = parseItem(t);
            result.add(parse);
        }

        return result;
    }
}
